<?php
/**
 * 组件类 - Memcache
 * 
 * @version $Id: Memcache.php 411 2012-12-31 08:03:18Z linsir123 $
 * @package Nosql
 */
class LpMemcache
{
	/**
	 * @var 实例
	 */
	private $_cache;
	
	/**
	 * 构造函数
	 * 
	 * @param array $servers 服务器列表
	 */
	public function __construct($servers = null)
	{
		$servers = App::O('main.mcServers');
		if ($servers && is_array($servers)) {
			$this->_cache = new Memcache();
			foreach ($servers as $server) 
				$this->addServer($server[0], $server[1]);
		} else 
			throw new Exception("[Memcache] 无法连接至服务器");
	}
	
	/**
	 * 构造函数
	 */
	public function __destruct()
	{
		if ($this->_cache) 
			$this->_cache->close();
	}
	
	/**
	 * 添加服务器
	 * 
	 * @param string $host 主机名
	 * @param int $port 端口号
	 * @return bool
	 */
	public function addServer($host, $port)
	{
		return $this->_cache->addServer($host, $port);
	}
	
	/**
	 * 添加数据（key存在则返回flase）
	 * 
	 * @param string $key 键名
	 * @param mixed $var 添加的数据
	 * @param int $expire 过期时间
	 * @return bool
	 */
	public function add($key, $var, $expire = 0)
	{
		if ($expire > 0)
			$expire += time();
			
		return $this->_cache->add($key, $var, 0, $expire);
	}
	
	/**
	 * 设置数据（可以用于替换）
	 * 
	 * @param string $key 键名
	 * @param mixed $var 添加的数据
	 * @param int $expire 过期时间
	 * @return bool
	 */
	public function set($key, $var, $expire = 0)
	{
		if ($expire > 0)
			$expire += time();
			
		return $this->_cache->set($key, $var, 0, $expire);
	}
	
	/**
	 * 取数据
	 * 
	 * @param string $key 键名
	 * @return mixed
	 */
	public function get($key)
	{
		return $this->_cache->get($key);
	}
	
	/**
	 * 清除数据
	 * 
	 * @param string $key 键名
	 * @param int $timeout 删除该元素的执行时间
	 * @return bool
	 */
	public function delete($key, $timeout = 0)
	{
		return $this->_cache->delete($key, $timeout);
	}
	
	/**
	 * 原子性递减
	 * 
	 * @param string $key 键名
	 * @param int $value 递减的值
	 * @return bool
	 */
	public function incr($key, $value = 1)
	{
		return $this->_cache->increment($key, $value);
	}
	
	/**
	 * 原子性递增
	 * 
	 * @param string $key 键名
	 * @param int $value 递增的值
	 * @return bool
	 */
	public function decr($key, $value = 1)
	{
		return $this->_cache->decrement($key, $value);
	}
	
	/**
	 * 对某个key创建一个锁
	 * 
	 * @param string $key 键名
	 * @param int $expire 过期时间
	 * @param string $prefix 前缀
	 */
	public function lock($key, $expire = 5, $prefix = 'lock:')
	{
		$key = $prefix.$key;
		while ( ! $this->add($key, 1, $expire)) 
			usleep(mt_rand(1, 5));
	}
	
	/**
	 * 解锁某个key
	 * 
	 * @param string $key 键名
	 * @param string $prefix 前缀
	 */
	public function unlock($key, $prefix = 'lock:')
	{
		$key = $prefix.$key;
		$this->delete($key);
	}
}
